package org.elzat.healthboxgatewayapp.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elzat.healthboxgatewayapp.config.HealthBoxJwtConfig;
import org.elzat.healthboxgatewayapp.credentials.HealthBoxAuthority;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static org.elzat.healthboxgatewayapp.config.HealthBoxJwtConfig.AUTHORITIES;

@Component
@Slf4j
public class HealthBoxJwt {

    private final HealthBoxJwtConfig healthBoxJwtConfig;
    private final SecretKey secretKey;
    public HealthBoxJwt(HealthBoxJwtConfig healthBoxJwtConfig, SecretKey secretKey) {
        this.healthBoxJwtConfig = healthBoxJwtConfig;
        this.secretKey = secretKey;
    }

    private Claims claims;
    public Boolean setClaims(String token) {
        Claims claims;
        try {
            claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
        } catch (Exception e) {
            log.error("exception occurred while parsing json web token");
            return false;
        }
        log.info("got claims from token: " + claims);
        this.claims = claims;
        return true;
    }
    public String getUserPhone() {
        return claims.getSubject();
    }
    public Date getExpirationDateFromToken() {
        return claims.getExpiration();
    }
    public Boolean isTokenExpired() {
        final Date expiration = getExpirationDateFromToken();
        return expiration.before(new Date());
    }
    public List<HealthBoxAuthority> getAuthorities() {
        List<String> authorities = claims.get(AUTHORITIES, List.class);
        List<HealthBoxAuthority> mapped = new ArrayList<>();
        for (String auth : authorities)
            mapped.add(HealthBoxAuthority.valueOf(auth));
        return mapped;
    }
    public String generateToken(UserDetails user) {
        return healthBoxJwtConfig.getTokenPrefix() +
                Jwts.builder()
                .setSubject(user.getUsername())
                .claim(AUTHORITIES, user.getAuthorities())
                .setIssuedAt(new Date())
                .setExpiration(healthBoxJwtConfig.getExpirationDate())
                .signWith(secretKey)
                .compact();
    }
}
